/// <reference path="appcommon.js"/>
/// <reference path="tfcore.js"/>
/// <reference path="tfNLog.js"/>

// #pragma NoCompStart
/*
tfcb.js  1.3
tfComboBox javascript functions
*/
// #pragma NoCompEnd
_TF = top;
TF = document;

var tfComboBox_optionTypes = [];

function tfRange(InputId, Start, End) {
    var Input = typeof (InputId) == 'object' ? InputId : _gE(InputId);
    try { Input.focus(); } catch (e) { };
    var Length = Input.value.length;
    Start--;
    if (Start < 0 || Start > End || Start > Length) Start = 0;
    if (End > Length) End = Length;
    if (Input.setSelectionRange) {
        Input.setSelectionRange(Start, End);
    }
    else if (Input.createTextRange) {
        var range = Input.createTextRange();
        range.moveStart('character', Start);
        range.moveEnd('character', End - Length);
        range.select();
    }
}
//var xml = (new tfXMLLoaderObject(this._fillControlsFromXML, this, true, true, xmlControl));
function tfXMLLoaderObject(funcObject, dynObject, rSeed, async, xmlControl) {
    var me = this;
    this.xmlDoc = "";
    if (typeof (async) != "undefined") { this.async = async; }
        else { this.async = true; }
    this.onloadAction = funcObject || null;
    this.mainObject = dynObject || null;
    this.waitCall = null;
    this.rSeed = rSeed || false;
    this.xmlControl = xmlControl || null;

    //private functions
    this.waitLoadFunction = function(dynObject) {
        var once = true;
        this.check = function() {
            if ((dynObject) && (dynObject.onloadAction != null)) {
                if ((!dynObject.xmlDoc.readyState) || (dynObject.xmlDoc.readyState == 4)) {
                    if (!once) { return; }
                    once = false;
                    dynObject.onloadAction(dynObject.mainObject, null, null, null, dynObject);
                    if (dynObject.waitCall) {
                        dynObject.waitCall();
                        dynObject.waitCall = null
                    }
                }
            }
        }
        return this.check
    };

    this.getXMLTopNode=function(tagName, oldObj) {
        if (this.xmlDoc.responseXML) {
            var temp = this.xmlDoc.responseXML.getElementsByTagName(tagName);
            var z = temp[0];
        }
        else var z = this.xmlDoc.documentElement;
        if (z) {
            this._retry = false;
            return z
        }
       
        if (_TF.is.ie && (!this._retry)) {
            
            var xmlString = this.xmlDoc.responseText;
            var oldObj = this.xmlDoc;
            this._retry = true;
            this.xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            this.xmlDoc.async = false;
            this.xmlDoc["loadXML"](xmlString);
            return this.getXMLTopNode(tagName, oldObj)
        }

        return document.createElement("DIV")
    };

    this._loadXMLString=function(xmlString, xmlControl) {
        try {
            var parser = new DOMParser();
            this.xmlDoc = parser.parseFromString(xmlString, "text/xml");
        }
        catch (e) {
            this.xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            this.xmlDoc.async = this.async;
            this.xmlDoc["loadXML"](xmlString)
        }

        this.onloadAction(this.mainObject, null, null, null, this);
        if (this.waitCall) {
            this.waitCall();
            this.waitCall = null
        }
    };

    this.destructor=function() { this.onloadAction = null; this.mainObject = null; this.xmlDoc = null; return null; };

    this.doXPath = function(xpathExp, docObj) {
        if (_TF.is.ie) {
            if (!docObj) { if (!this.xmlDoc.nodeName) { docObj = this.xmlDoc.responseXML; } else { docObj = this.xmlDoc; } }
            return docObj.selectNodes(xpathExp);
        }
        else {
            var nodeObj = docObj;
            if (!docObj) {
                if (!this.xmlDoc.nodeName) {
                    docObj = this.xmlDoc.responseXML;
                }
                else {
                    docObj = this.xmlDoc;
                }
            }
            if (docObj.nodeName.indexOf("document") != -1) {
                nodeObj = docObj;
            }
            else {
                nodeObj = docObj;
                docObj = docObj.ownerDocument;
            }
            var rowsCol = [];
            var col = docObj.evaluate(xpathExp, nodeObj, null, XPathResult.ANY_TYPE, null);
            var thisColMemb = col.iterateNext();
            while (thisColMemb) {
                rowsCol[rowsCol.length] = thisColMemb;
                thisColMemb = col.iterateNext();
            }
            return rowsCol;
        }
    };

} // end tfXMLLoaderObject

function tfJSONLoaderObject(funcObject, dynObject, rSeed, async, jsonControl) {
    var me = this;
    this.jsonDoc = "";
    if (typeof (async) != "undefined") { this.async = async; }
    else { this.async = true; }
    this.onloadAction = funcObject || null;
    this.mainObject = dynObject || null;
    this.waitCall = null;
    this.rSeed = rSeed || false;
    this.jsonControl = jsonControl || null;

    //private functions
    this.waitLoadFunction = function(dynObject) {
        var once = true;
        this.check = function() {
            if ((dynObject) && (dynObject.onloadAction != null)) {
                if ((!dynObject.xmlDoc.readyState) || (dynObject.xmlDoc.readyState == 4)) {
                    if (!once) { return; }
                    once = false;
                    dynObject.onloadAction(dynObject.mainObject, null, null, null, dynObject);
                    if (dynObject.waitCall) {
                        dynObject.waitCall();
                        dynObject.waitCall = null
                    }
                }
            }
        }
        return this.check
    };

    this.loadJSON = function(jsonobj, xmlControl) {
        try {
            var parser = new DOMParser();
            this.xmlDoc = parser.parseFromString(xmlString, "text/xml");
        }
        catch (e) {
            this.xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            this.xmlDoc.async = this.async;
            this.xmlDoc["loadXML"](xmlString)
        }

        this.onloadAction(this.mainObject, null, null, null, this);
        if (this.waitCall) {
            this.waitCall();
            this.waitCall = null
        }
    };

    this.destructor = function() { this.onloadAction = null; this.mainObject = null; this.xmlDoc = null; return null; };
} // end tfJSONLoaderObject

function tfComboBox_base() {
    this.value = null;
    this.text = "";
    this.xdata="";
    this.selected = false;
    this.fiText = "";
    this.css = "";

    this.select = function() { if (this.content) { this.content.className = "tfCBN tfSelected_option"; } };

    this.hide = function(mode) { this.render().style.display = mode ? "none" : ""; };
    this.isHidden = function() { return (this.render().style.display == "none"); };
    this.deselect = function() { if (this.content) { this.render(); } this.content.className = "tfCBN"; };
    this.setValue = function(attr) {
        this.value = attr.value || "";
        this.text = attr.text || "";
        this.css = attr.css || "";
        this.fiText = attr.fiText || "";
        this.content = null;
    };

    this.render = function() {
        if (!this.content) {
            this.content = document.createElement("div");
            this.content._self = this;
            this.content.style.cssText = "'width:100%;overflow:hidden;" + this.css + "'";
            this.content.innerHTML = this.text;
            this._ctext = _TF.is.ie ? this.content.innerText : this.content.textContent;
        }
        return this.content;
    };

    this.data = function() { if (this.content) return [this.value, this._ctext ? this._ctext : this.text]; };

    this.DrawHeader = function(self, name, width, height, tab) {
        var z = document.createElement("div");
        z.style.width = width + "px";
        z.className = 'tfCombo_box';
        z.id = name + "cb";
        z._self = self;
        self.DOMelem = z;
        this._DrawHeaderInput(self, name, width, height, tab);
        this._DrawHeaderButton(self, name, width);
        self.DOMParent.appendChild(self.DOMelem)
    };

    this._DrawHeaderInput = function(self, name, width, height, tab) {
        var z = document.createElement('input');
        z.className = 'tfCombo_input';
        z.type = 'text';
        if (tab) z.tabIndex = tab;
        z.style.width = (width - 19) + 'px';
        self.DOMelem.appendChild(z);
        self.DOMelem_input = z;
        z = document.createElement('input');
        z.type = 'hidden';
        z.name = name;
        self.DOMelem.appendChild(z);
        self.DOMelem_hidden_input = z;
        z = document.createElement('input');
        z.type = 'hidden';
        z.name = name + "_new_value";
        z.value = "true";
        self.DOMelem.appendChild(z);
        self.DOMelem_hidden_input2 = z;
    };


    this._DrawHeaderButton = function(self, name, width) {
        var z = document.createElement('div');
        z.className = 'tfCombo_img';
        //z.src = (window.AppComboImgPath ? AppComboImgPath : "") + 'combo_select.gif';
        self.DOMelem.appendChild(z);
        self.DOMelem_button = z;
    };

    this.DrawFooter = function(self, optionType, name, width) {
        var z = document.createElement('div');
        z.className = 'Footer';
        z.style.width = '100%'; // width + 8 + 'px';
        var nArr = [];
        nArr.push('<table border="0" width="100%" cellpadding="0" cellspacing="0"><tr><td class="lC"></td>');

        nArr.push('<td class="c">');
        
        if (optionType == 'checkbox') {
            nArr.push('<span style="float:left;"><a class="leftLink" href="javascript:' + name + '.setChecked(true);">Check All</a> | <a class="leftLink" href="javascript:' + name + '.setChecked(false);">Uncheck All</a></span>');
        }

        nArr.push('<span style="float:right;"><a class="rightLink" href="javascript:' + name + '.closeAll();">Close</a></span></td>');
        nArr.push('<td class="rC"></td></tr></table>');
        z.innerHTML = nArr.join('');
        self.appendChild(z);
    };

    this.RedrawHeader = function(self) { };

} // end tfComboBox_base


function tfComboBox_imageOption() {
    me = new tfComboBox_base;

    this.setValue = function(attr) {
        this.value = attr.value || ""; this.text = attr.text || ""; this.fiText = attr.fiText || ""; this.css = attr.css || ""; this.img_src = attr.img_src || this.getDefImage();
    };

    this.render = function() {
        if (!this.content) {
            this.content = document.createElement("div");
            this.content._self = this;
            this.content.style.cssText = 'width:100%; overflow:hidden; ' + this.css;
            var html = '';
            if (this.img_src != '') html += '<img style="float:left;width:18px;height:20px;" src="' + this.img_src + '" />';
            html += '<div style="float:left">' + this.text + '</div>';
            this.content.innerHTML = html;
            //this.content.firstChild.onclick = function(e) {(e||event).cancelBubble=true;}
        }
        return this.content;
    };
    this.data = function() {
        return [this.value, this.text, this.img_src];
    };
    this.DrawHeader = function(self, name, width) {
        var z = document.createElement("div");
        z.style.width = width + "px";
        z.className = 'tfCombo_box';
        z.id = name + "cb";
        z._self = self;
        self.DOMelem = z;
        this._DrawHeaderImage(self, name, width);
        this._DrawHeaderInput(self, name, width - 18);
        this._DrawHeaderButton(self, name, width);
        self.DOMParent.appendChild(self.DOMelem);
    };
    this._DrawHeaderImage = function(self, name, width) {
        var z = document.createElement('img');
        //z.src='';
        z.className = 'tfCombo_option_img';
        z.style.visibility = 'hidden';
        self.DOMelem.appendChild(z);
        self.DOMelem_image = z;
    };
    this.RedrawHeader = function(self) {
        self.DOMelem_image.style.visibility = 'visible';
        self.DOMelem_image.src = this.img_src;
    };
    this.getDefImage = function(self) {
        return "";
    };

    this.init();

} // End tfComboBox_imageOption

function tfComboBox_checkboxOption() {
    var _me = new tfComboBox_base();

    _me.setValue = function(attr) {
        _me.value = attr.value || "";
        _me.text = attr.text || "";
        _me.fiText = attr.fiText;
        _me.css = attr.css || "";
    };

    _me.render = function() {
        if (!_me.content) {
            if (_me.text == "Select A Value") {
                _me.content = document.createElement("div");
                _me.content._self = this;
                _me.content.ID = "cdDef";
                _me.content.className = 'edCBN hidden';
                _me.content.innerHTML = _me.text;
                return _me.content;
            }
            _me.content = document.createElement("div");
            _me.content._self = this;
            _me.content.className = 'edCBN';
            _me.content.style.cssText = _me.css;
            var html = '<input type="checkbox"';
            if (_me.css == true) html += ' checked';
            html += ' ></input>' + _me.text + '';
            _me.content.innerHTML = html;
            _me.content.firstChild.onclick = function(e) { (e || event).cancelBubble = true; };
        }
        return _me.content;
    };

    _me.data = function() { return [_me.value, _me.text, _me.render().firstChild.checked]; };

    _me._DrawHeaderCheckbox = function(self, name, width) {
        var z = document.createElement('input');
        z.type = 'checkbox';
        z.style.visibility = 'hidden';
        z.onclick = function(e) { (e || event).cancelBubble = true; };
        self.DOMelem.appendChild(z);
        self.DOMelem_checkbox = z;
    };


    _me.DrawHeader = function(self, name, width) {
        self.DOMelem = document.createElement("div");
        self.DOMelem.style.width = width + "px";
        self.DOMelem.className = 'tfCombo_box';
        self.DOMelem.id = name + "cb";
        self.DOMelem._self = self;
        _me._DrawHeaderCheckbox(self, name, width);
        _me._DrawHeaderInput(self, name, width - 18);
        _me._DrawHeaderButton(self, name, width);
        self.DOMParent.appendChild(self.DOMelem);
    };

    _me.RedrawHeader = function(self) {
        if (_me.text == self.fiText) self.DOMelem_checkbox.style.display = 'none';
        else self.DOMelem_checkbox.style.visibility = 'visible';
    };

    return _me;
}  // end checkbox


/*	Secondary Value Option */
function tfComboBox_xdataOption() {
    var _me = new tfComboBox_base;
    
    _me.setValue = function(attr) {
        _me.xdata = attr.xdata || ""; 
        _me.value = attr.value || "";
        _me.text = attr.text || "";
        _me.css = attr.css || "";
    };

    _me.data = function() { return [this.xdata, this.value, this.text]; };

    return _me;
}

tfComboBox_optionTypes['default'] = tfComboBox_base;
tfComboBox_optionTypes['xdata'] = tfComboBox_xdataOption;
tfComboBox_optionTypes['checkbox'] = tfComboBox_checkboxOption;
tfComboBox_optionTypes['image'] = tfComboBox_imageOption;

// Resizeable Drop Down functions
var dragBarWidth = 10;
function onDragStart(ele, mx, my) {
    var x = TF.X.PageX(ele);
    var y = TF.X.PageY(ele);
    var hy = TF.X.Height(ele);
    if (my <= y+hy) { return; }
    if (mx >= x + TF.X.Width(ele) - dragBarWidth) {
        ele.isRightResize = true;
    }
    else if (mx <= x + dragBarWidth) {
        ele.isLeftResize = true;
    }
}
function onDrag(ele, mdx, mdy) {
    var w = TF.X.Width(ele);

    if (ele.isRightResize) {
        w += mdx;
        if (w >= 3 * dragBarWidth) TF.X.Width(ele, w);
        w = TF.X.Width(ele);
    }
    else if (ele.isLeftResize) {
        w -= mdx;
        if (w >= 3 * dragBarWidth) {
            var x = ele.isRelativePos ? TF.X.Left(ele) : TF.X.PageX(ele);
            TF.X.Left(ele, x + mdx);
            TF.X.Width(ele, w);
        }
    }
}
function onDragEnd(ele, mx, my) {
    ele.isRightResize = false;
    ele.isLeftResize = false;
}

//start tfCombobox
function tfComboBox(parent, name, width, ddwidth, height, fiText, optionType, tabIndex) {
    var _me = this;
    if (typeof (parent) != null) { parent = _gE(parent); var changeevent = parent.onchange; }
    this.optionType = (optionType != window.undefined && tfComboBox_optionTypes[optionType]) ? optionType : 'default';
    this._optionObject = tfComboBox_optionTypes[this.optionType];
    this._disabled = false;
    this._RootEl = _gE(name);

    if (!window._tfSelectAr) {
        window._tfSelectAr = [];
        window._tfOpenedSelect = null;
        window._tfSelectId = 1;
        // //shortcut.add('tab', function() { alert(1); this.closeAll(); return true; }, { 'target': parent }, _me, true);
        //shortcut.add('tab', function() { window._tfSelectAr[0].closeAll(); return true; }, {});
        // //edAddEvent(this, "keydown", function(e) { try { if ((e || event).keyCode == 9) this.closeAll(); } catch (e) { }; return true; });
    }

    this.setSize = function(new_size) {
        this.DOMlist.style.width = new_size + "px";
        if (this.DOMlistF) { this.DOMlistF.style.width = new_size + "px"; }
        this.DOMelem.style.width = new_size + "px";
        this.DOMelem_input.style.width = (new_size - 19) + 'px';
    };

    this.enableFilteringMode = function(mode, url, cache, autosubload) {

    this.enableTypeAheadMode = function(bMode) { this._typeAhead = toBoolean(bMode); };
    
    this._filter = _TF.String.toBoolean(mode);
    if (url) { this._xml = url; this._autoxml = _TF.String.toBoolean(autosubload); }
    if (_TF.String.toBoolean(cache)) { this._xmlCache = []; }
    };

    this.setFilteringParam = function(name, value) { if (!this._prs) { this._prs = []; } this._prs.push([name, value]); };

    this.disable = function(mode) {
    var z = _TF.String.toBoolean(mode);
        if (this._disabled == z) return;
        this.DOMelem_input.disabled = z;
        this._disabled = z;
    };

    this.clearAll = function(all) {
        if (all) this.setComboText("");
        this.optionsArr = [];
        this.redrawOptions();
        if (all) { this._onChange.apply(this.DOMelem_input, []); }
    };

    this.deleteOption = function(value) {
        var ind = this.getIndexbyValue(value);
        if (ind < 0) return;
        if (this.optionsArr[ind] == this._selOption) { this._selOption = null; }
        this.optionsArr.splice(ind, 1);
        this.redrawOptions();
    };

    this.render = function(mode) { this._skiprender = (!_TF.String.toBoolean(mode)); this.redrawOptions(); };
    this.updateFirstItem = function(avalue, atext, acss) { this.optionsArr[0].text = atext; };

    this.updateOption = function(oldvalue, xavalue, avalue, atext, acss) {
        var dOpt = this.getOption(oldvalue);
        if (typeof (avalue) != "object") { avalue = { xdata: xavalue, text: atext, value: avalue, css: acss }; }
        dOpt.setValue(avalue); this.redrawOptions();
    };

    this.addOption = function(options) {
        if (!arguments[0].length || typeof (arguments[0]) != "object") { args = [arguments]; }
        else { args = options; }
        this.render(false);
        for (var i = 0; i < args.length; i++) {
            var attr = args[i];
            if (attr.length) {
                if (this.optionType == "xdata") {
                    attr.xdata = attr[0] || ""; attr.value = attr[1] || ""; attr.text = attr[2] || ""; attr.css = attr[3] || "";
                }
                else {
                    attr.value = attr[0] || ""; attr.text = attr[1] || ""; attr.css = attr[2] || "";
                }
            }
            this._addOption(attr);
        }
        this.render(true);
    };

    this._addOption = function(attr) {
        dOpt = new this._optionObject();
        this.optionsArr.push(dOpt);
        dOpt.setValue.apply(dOpt, [attr]);
        this.redrawOptions();
    };

    this.readonly = function(mode) { this.DOMelem_input.readOnly = mode ? true : false; };
    this.getOption = function(value) { for (var i = 0; i < this.optionsArr.length; i++) { if (this.optionsArr[i].value == value) { return this.optionsArr[i]; } } return null; };
    this.getOptionByLabel = function(value) { for (var i = 0; i < this.optionsArr.length; i++) { if (this.optionsArr[i].text == value) { return this.optionsArr[i]; } } return null; };
    this.getOptionByIndex = function(ind) { return this.optionsArr[ind]; }; this.getIndexByValue = function(value) { for (var i = 0; i < this.optionsArr.length; i++) { if (this.optionsArr[i].value == value) { return i; } } return -1; };
    this.getSelectedValue = function() { return (this._selOption ? this._selOption.value : null); };
    this.getComboText = function() { return this.DOMelem_input.value; };
    this.getCombofiText = function() { return this.fiText; };
    this.setComboText = function(text) { this.DOMelem_input.value = text; };
    this.getActualValue = function() { return this.DOMelem_hidden_input.value; };
    this.getSelectedText = function() { return (this._selOption ? this._selOption.text : ""); };
    this.getSelectedIndex = function() { for (var i = 0; i < this.optionsArr.length; i++) { if (this.optionsArr[i] == this._selOption) { return i; } } return -1; };
    this.setName = function(name) { this.DOMforSbm.name = name; this.name = name; };
    this.getName = function() { return this.name; };
    this.getList = function() { return this.optionsArr; };

    this.setComboValue = function(text) {
        this.setComboText(text);
        for (var i = 0; i < this.optionsArr.length; i++) if (this.optionsArr[i].data()[1] == this.DOMelem_input.value) return this.selectOption(i);
        this.DOMelem_hidden_input.value = text;
    };

    this.show = function(mode) { if (_TF.String.toBoolean(mode)) { this.DOMelem.style.display = ""; } else { this.DOMelem.style.display = "none"; } };

    this.destructor = function() {
        var _sID = this._inID;
        this.DOMParent.removeChild(this.DOMelem);
        this.DOMlist.parentNode.removeChild(this.DOMlist);
        var s = _tfSelectAr;
        this.DOMParent = this.DOMlist = this.DOMelem = 0;
        this.DOMlist.combo = this.DOMelem.combo = 0;
        for (var i = 0; i < s.length; i++) {
            if (s[i]._inID == _sID) {
                this._selectsArr[i] = null;
                this._selectsArr.splice(i, 1);
                return;
            }
        }
    };

    this._createSelf = function(selParent, name, width, ddwidth, height, tab, fiText) {
        if (width.toString().indexOf("%") != -1) {
            var self = this;
            var resWidth = parseInt(width) / 100;
            window.setInterval(function() {
                var ts = selParent.parentNode.offsetWidth * resWidth - 2; if (ts == self._lastTs) return; self.setSize(self._lastTs = ts)
            }, 500);
            height = parseInt(selParent.offsetHeight);
            width = parseInt(selParent.offsetWidth);
        }

        this.fiText = fiText;
        width = parseInt(width || 200);
        height = parseInt(height || 200);
        ddwidth = parseInt(ddwidth || 200);
        this.ListPosition = "Bottom";
        this.DOMParent = selParent;
        this._inID = null;
        this.name = name;
        this._selOption = null;
        this.optionsArr = [];
        var opt = new this._optionObject();
        opt.DrawHeader(this, name, width, height, tab);

        this.DT = document.createElement("DIV");
        this.DT.className = 'tfCBResize';
        this.DT.id = name + 'rs';
        this.DT.style.width = ddwidth + "px";
        this.DT.style.height = height + "px";
        this.DT.style.display = "none";

        if (_TF.is.ie) {
            this.DOMlistF = document.createElement("IFRAME");
            this.DOMlistF.style.border = "0px";
            this.DOMlistF.className = 'tfCBResize';
            this.DOMlistF.style.width = '100%'; //ddwidth - (_TF.is.ie ? 0 : 0) + "px";
            this.DOMlistF.style.height = '100%'; //height + 2 - (_TF.is.ie ? 0 : 0) + "px";
            this.DOMlistF.style.display = "none";
            this.DOMlistF.src = "javascript:false;";
            this.DT.appendChild(this.DOMlistF);
        };

        this.DOMlist = document.createElement("DIV");
        this.DOMlist.className = 'tfCBList';
        this.DOMlist.style.width = '100%'; 
        this.DOMlist.style.height = height + 'px';  
        this.DT.appendChild(this.DOMlist);
        this._RootEl.appendChild(this.DT);
        opt.DrawFooter(this.DT, this.optionType, name, ddwidth);

        this.DOMlist.combo = this.DOMelem.combo = this;
        _AddEvent(this.DOMelem_input, "keypress", this._onKey);
        _AddEvent(this.DOMelem_input, "keydown", this._onKey);
        this.DOMelem_input.onblur = this._onChange;
        this.DOMelem.onclick = this._toggleSelect;
        _AddEvent(this.DOMlist, "keypress", this._onKey);
        _AddEvent(this.DOMlist, "keydown", this._onKey);

        this.DOMlist.onclick = this._selectOption;
        this.DOMlist.onmouseover = this._listOver;

        _TF.Element.EnableDrag(this.DT.id, onDragStart, onDrag, onDragEnd);
        if (TF.X.GetComputedStyle(this.DT, 'position') == 'relative') { this.DT.isRelativePos = true; }

    };

    this._listOver = function(e) {
        e = e || event;
        e.cancelBubble = true;
        var node = (_TF.is.ie ? event.srcElement : e.target);
        var that = this.combo;
        if (node.parentNode == that.DOMlist) {
            that.unSelectOption();
            var i = 0;
            for (i; i < that.DOMlist.childNodes.length; i++) {
                if (that.DOMlist.childNodes[i] == node) break
            };
            var z = that.optionsArr[i];
            that._selOption = z;
            that._selOption.select();
            if ((that._autoxml) && ((i + 1) == that._lastLength)) that._fetchOptions(i + 1, that._lasttext || "");
        }
    };

    this._positList = function() {
        var pos = this.getPosition(this.DOMelem);
        if (this.ListPosition == 'Bottom') {
            this.DT.style.top = pos[1] + this.DOMelem.offsetHeight + "px";
            this.DT.style.left = pos[0] + "px";
        }
        else {
            this.DT.style.top = pos[1] + "px";
            this.DT.style.left = pos[0] + this.DOMelem.offsetWidth + "px";
        }
    };

    this.getPosition = function(oNode, pNode) {
        var iLeft = TF.X.OffsetLeft(oNode);
        var iTop = TF.X.OffsetTop(oNode);
        return [iLeft, iTop];
    };

    this._correctSelection = function() {
        if (this.getComboText() != "") for (var i = 0; i < this.optionsArr.length; i++) if (!this.optionsArr[i].isHidden()) {
            return this.selectOption(i, true);
        }
        this.unSelectOption();
    };

    this.selectNext = function(step) {
        var z = this.getSelectedIndex() + step;
        while (this.optionsArr[z]) {
            if (!this.optionsArr[z].isHidden()) return this.selectOption(z);
            z += step;
        }
    };

    this._onKey = function(e) {
        var that = this.parentNode.combo;
        (e || event).cancelBubble = true;
        var ev = (e || event).keyCode;

        if (ev == 9 || ev == 13) {
            that.DOMelem.onclick(e || event);
            that.closeAll();
            if (ev == 13) { return false; }
        }
        else if (ev == 27) {
            that.closeAll();
            // that.callEvent("onKeyPressed", [ev.keyCode]); 
            return false;
        }
        else {
            if ((that.DT.style.display != "block") && ((!that._filter) || (that._filterAny))) {
                that.DOMelem.onclick(e || event);
            }
            window.setTimeout(function() { that._onKeyB(ev); }, 1);
        }
    };

    this._onKeyB = function(ev) {
        if (ev == "40") { var z = this.selectNext(1); }
        else if (ev == "38") { this.selectNext(-1); }
        else {
            if (this.onkeypressed) { this.onkeypressed(ev); }
            if (this._filter) return this.filterSelf((ev == 8) || (ev == 46));

            if (this._typeAhead) return this.filterSelf((ev == 8) || (ev == 46));

            for (var i = 0; i < this.optionsArr.length; i++) {
                if (this.optionsArr[i].data()[1] == this.DOMelem_input.value) {
                    this.selectOption(i);
                    return false;
                }
            }
            this.unSelectOption();
        }
        return true;
    };

    this._onChange = function() {
        var self = this.parentNode._self;
        var z = self.getOptionByLabel(self.DOMelem_input.value);
        self.DOMelem_hidden_input.value = z ? z.value : self.DOMelem_input.value;
        self.DOMelem_hidden_input2.value = (z == null);
        if (self.onblur) { self.onblur(); }
        self.callEvent("onBlur", []);
        _RaiseEvent(self.name, "OnChange", self.DOMelem_hidden_input.value);
    };

    this.redrawOptions = function() {
        if (this._skiprender) { return; }
        for (var i = this.DOMlist.childNodes.length - 1; i >= 0; i--) { this.DOMlist.removeChild(this.DOMlist.childNodes[i]); }
        for (var i = 0; i < this.optionsArr.length; i++) { this.DOMlist.appendChild(this.optionsArr[i].render()); }
    };

    this.loadXMLString = function(astring, xmlControl) {
        var xml = (new tfXMLLoaderObject(this._fillControlsFromXML, this, true, true, xmlControl));
        xml._loadXMLString(astring, xmlControl);
    };

    this._fillControlsFromXML = function(obj, b, c, d, xml) {
        if (obj._xmlCache) obj._xmlCache[xml._cPath] = xml;
        xml.getXMLTopNode("list");
        var top = xml.doXPath("/list");
        var controls = xml.doXPath("//ctrl");
        var options = xml.doXPath("/list/ctrl[@id='" + xml.xmlControl + "']//opt");
        obj.render(false);
        if ((!top[0]) || (!top[0].getAttribute("add"))) {
            obj.clearAll();
            obj._lastLength = options.length;
            if (obj._xml) {
                if ((!options) || (!options.length)) obj.closeAll();
                else {
                    obj.DT.style.display = "block";
                    if (_TF.is.ie) { obj._IEFix(true); }
                }
            }
        }
        else obj._lastLength += options.length;
        var cLen = options.length;
        for (var i = 0; i < cLen; i++) {
            var attr = new Object();
            attr.text = options[i].firstChild ? options[i].firstChild.nodeValue : "";
            var cAttrlen = options[i].attributes.length;
            for (var j = 0; j < cAttrlen; j++) {
                var a = options[i].attributes[j];
                if (a) attr[a.nodeName] = a.nodeValue;
            }
            if (a.nodeName == "selected" || a.nodeName == "checked") attr.css = true;
            obj._addOption(attr)
        };
        obj.render(true);
        if ((obj._load) && (obj._load !== true)) obj.loadXML(obj._load);
        else {
            obj._load = false;
            if ((!obj._lkmode) && (!obj._filter)) { obj._correctSelection(); }
        }
        var selected = xml.doXPath("/list/ctrl[@id='" + xml.xmlControl + "']/opt[@selected]");

        if (selected.length) { obj.selectOption(obj.getIndexByValue(selected[0].getAttribute("value"))); } else {
            obj.selectOption(0);
        }
    };

    this.unSelectOption = function() { if (this._selOption) { this._selOption.deselect(); } this._selOption = null; };
    this.selectOption = function(ind, filter, typeahead) {
        this.unSelectOption();
        var z = this.optionsArr[ind];
        if (!z) { return; }
        var di = this.optionType == "xdata" ? 1 : 0;
        this._selOption = z;
        this._selOption.select();

        var corr = this._selOption.content.offsetTop + this._selOption.content.offsetHeight - this.DOMlist.scrollTop - this.DOMlist.offsetHeight;
        if (corr > 0) this.DOMlist.scrollTop += corr;
        corr = this.DOMlist.scrollTop - this._selOption.content.offsetTop;
        if (corr > 0) this.DOMlist.scrollTop -= corr;
        if (typeahead) { return; }
        var data = this._selOption.data();
        this.DOMelem_hidden_input.value = data[di];
        this.DOMelem_hidden_input2.value = "false";
        if ((this._autoxml) && ((ind + 1) == this._lastLength)) { this._fetchOptions(ind + 1, this._lasttext || ""); }
        if (filter) {
            var text = this.getComboText();
            if (text != data[di+1]) {
                this.setComboText(data[di+1]);
                tfRange(this.DOMelem_input, text.length + 1, data[di+1].length);
            }
        }
        else {
                this.setComboText(data[di+1]);
        }
        this._selOption.RedrawHeader(this);
        this.callEvent("onChange", []);
    };

    this._selectOption = function(e) {
        (e || event).cancelBubble = true;
        var node = (_TF.is.ie ? event.srcElement : e.target);
        var that = this.combo;
        if (that == null) { that = this; }
        while (!node._self) { node = node.parentNode; if (!node) return; }
        var i = 0;

        if (that.optionType != 'checkbox') {
            for (i; i < that.DOMlist.childNodes.length; i++) { if (that.DOMlist.childNodes[i] == node) break; }
            that.selectOption(i);
        }
        else {
            that.getChecked();
        }
        that.closeAll();
        _RaiseEvent(that.name, "OnChange", i);
        
    };

    this.openSelect = function() {
        if (this._disabled) return;
        this.closeAll();
        this._positList();
        this.DT.style.display = "block";
        if (this.autoOptionSize) {
            var x = this.DOMlist.offsetWidth;
            for (var i = 0; i < this.optionsArr.length; i++) { if (this.DOMlist.childNodes[i].scrollWidth > x) { x = this.DOMlist.childNodes[i].scrollWidth; } }
            this.DOMlist.style.width = x + "px"
        }
        if (_TF.is.ie) { this._IEFix(true); }
        this.DOMelem_input.focus();
        if (this._filter) this.filterSelf()
    };
    this._toggleSelect = function(e) {
        var that = this.combo;
        if (that.DT.style.display == "block") { that.closeAll(); } else { that.openSelect(); }
        (e || event).cancelBubble = true;
    };

    this._fetchOptions = function(ind, text) {
        if (text == "") { this.closeAll(); return this.clearAll(); }
        var url = this._xml + ((this._xml.indexOf("?") != -1) ? "&" : "?") + "pos=" + ind + "&mask=" + encodeURI(text);
        this._lasttext = text;
    };

    this.filterSelf = function(mode) {
        var text = this.getComboText();
        if ((text == this.fiText) || (text == 'Multiple Values Selected')) { text = ""; }
        if (this._xml) {
            this._lkmode = mode;
            this._fetchOptions(0, text)
        }
        try {
            var filter = new RegExp("^" + text, "i");
        }
        catch (e) {
            var filter = new RegExp("^" + text.replace(/([\[\]\{\}\(\)\+\*\\])/g, "\\$1"));
        }
        this.filterAny = false;

        for (var i = 0; i < this.optionsArr.length; i++) {
            var z = filter.test(escape(this.optionsArr[i].text));
            this.filterAny |= z;
            if (this._filter) { this.optionsArr[i].hide(!z); }
            if (this._typeAhead && z) {
                if (!mode) { this.selectOption(i, true, false); return; }
            }
        }

        if (!this.filterAny && this._filter) this.closeAll();
        else {
            if (this.DT.style.display != "block") this.openSelect();
            if (is.ie) this._IEFix(true);
        }

        if (!mode) { this._correctSelection(); }
        else { this.unSelectOption(); }
    };


    this._IEFix = function(mode) { this.DOMlistF.style.display = (mode ? "block" : "none"); this.DOMlistF.style.top = this.DOMlist.style.top; this.DOMlistF.style.left = this.DOMlist.style.left; };

    this.closeAll = function() {
        if (window._tfSelectAr) {
            for (var i = 0; i < _tfSelectAr.length; i++) {
                if (_tfSelectAr[i].DT.style.display == "block") {
                    _tfSelectAr[i].DT.style.display = "none";
                    if (_tfSelectAr[i].optionType == "checkbox") { _tfSelectAr[i].getChecked(); }
                    if (_TF.is.ie) _tfSelectAr[i]._IEFix(false);
                    try {
                        if (typeof _tfSelectAr[i].xmlList.value == "string") { _tfSelectAr[i].xmlList.value = _tfSelectAr[i].getXMLList(_tfSelectAr[i].name); }
                        _RaiseEvent(_tfSelectAr[i], "OnChange", i);
                    } catch (e) { }
                }
            }
        }
    };
    this.getXMLList = function(xmlControl) {
        var optCnt = this.optionsArr.length;
        var res = '<ctrl id="' + xmlControl + '">';
        for (var i = 0; i < optCnt; i++) {
            res += '<opt value="' + this.optionsArr[i].value + '" ';
            if (this.optionType == 'xdata') { res += 'xdata="' + this.optionsArr[i].xdata + '" '; }
            if (this.optionsArr[i] == this._selOption || (this.optionType == 'checkbox' && this.optionsArr[i].data()[2])) { res += 'selected="true"'; }
            res += '>' + this.optionsArr[i].text + '</opt>';
        }
        res += '</ctrl>';
        return res;
    };

    this.tfEvent = function() {
        this.tfSeverCatcherPath = "";
        this.attachEvent = function(original, catcher, CallObj) {
            CallObj = CallObj || this;
            original = 'ev_' + original;
            if ((!this[original]) || (!this[original].addEvent)) {
                var z = new this.eventCatcher(CallObj);
                z.addEvent(this[original]);
                this[original] = z;
            }
            return (original + ':' + this[original].addEvent(catcher));
        };

        this.callEvent = function(name, arg0) { if (this["ev_" + name]) { return this["ev_" + name].apply(this, arg0); } return true; };
        this.checkEvent = function(name) { if (this["ev_" + name]) { return true; } return false; };

        this.eventCatcher = function(obj) {
            var tfCatch = [];
            var m_obj = obj;
            var func_server = function(catcher, rpc) {
                catcher = catcher.split(":");
                var postVar = "";
                var postVar2 = "";
                var target = catcher[1];
                if (catcher[1] == "rpc") {
                    postVar = '<?xml version="1.0"?><methodCall><methodName>' + catcher[2] + '</methodName><params>';
                    postVar2 = "</params></methodCall>";
                    target = rpc;
                }
                var z = function() { };
                return z;
            };

            var z = function() {
                if (tfCatch) var res = true;
                for (var i = 0; i < tfCatch.length; i++) {
                    if (tfCatch[i] != null) {
                        var zr = tfCatch[i].apply(m_obj, arguments);
                        res = res && zr;
                    }
                }
                return res;
            };

            z.addEvent = function(ev) {
                if (typeof (ev) != "function") if (ev && ev.indexOf && ev.indexOf("server:") == 0) { ev = new func_server(ev, m_obj.rpcServer); }
                else { ev = eval(ev); }
                if (ev) { return tfCatch.push(ev) - 1; }
                return false;
            };
            z.removeEvent = function(id) { tfCatch[id] = null; };

            return z;
        };

        this.detachEvent = function(id) {
            if (id != false) { var list = id.split(':'); this[list[0]].removeEvent(list[1]); }
        };
    };

    this.setChecked = function(bSelected) {
        var allItems = this._RootEl.getElementsByTagName('input');
        for (var i = 0; i < allItems.length; i++) {
            if (allItems[i].type == 'checkbox') {
                if (allItems[i].parentNode.style.display != "none") { allItems[i].checked = bSelected; }
            }
        }
        this.getChecked();
    };

    this.getChecked = function() {
        var res = [];
        var ind = 0;
        for (var i = 0; i < this.optionsArr.length; i++) {
            if (this.optionsArr[i].data()[2]) { res.push(this.optionsArr[i].value); ind = i; }
        }

        if (res.length < 2) {
            if (ind == 0) { this.updateFirstItem("", "Select A Value"); this.selectOption(0); } else { this.selectOption(ind); }
        }
        else {
            this.updateFirstItem("", "Multiple Values Selected"); this.selectOption(0);
        }
        return res;
    };

    this.getCheckedCount = function() {
        var c = 0;
        for (var i = 0; i < this.optionsArr.length; i++) { if (this.optionsArr[i].data()[2]) { c++; } }
        return c;
    };

    this.tfEvent();
    this._ChangeEvent = changeevent;
    this._createSelf(parent, name, width, ddwidth, height, tabIndex, fiText);
    _tfSelectAr.push(this);
    _AddEvent(document.body, "click", this.closeAll);
   
    //shortcut.add('tab', function() { this.closeAll(); return true; }, { 'target': parent }, _me, true);
    if (parent.childNodes[0]) { this.xmlList = _gE(parent.childNodes[0].id); }
    this.loadXMLString('<?xml version=\"1.0\" ?><list>' + this.xmlList.value + '</list>', name);
} //end tfComboBox
